﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Stone
{
    public class GPGGA
    {
        public string NMEA_string = ""; 

        //Variables
        private DateTime _timeOfFix;
        private Coordinate _position;
        private FixQualityEnum _fixQuality;
        private byte _noOfSats;
        private double _altitude;
        private char _altitudeUnits;
        private double _dilution;
        private double _heightOfGeoid;
        private int _dGPSUpdate;
        private string _dGPSStationID;
        
        //Enumerations
        public enum FixQualityEnum { Invalid = 0, GPS = 1, DGPS = 2 }

        //Methods
        public GPGGA()
        {
            _position = new Coordinate();
        }
        public GPGGA(string NMEAsentence)
        {
            NMEA_string = NMEAsentence;

            try
            {
                if (NMEAsentence.IndexOf('*') > 0)
                    NMEAsentence = NMEAsentence.Substring(0, NMEAsentence.IndexOf('*'));
                //Split into an array of strings.
                string[] split = NMEAsentence.Split(new Char[] { ',' });
                if (split[1].Length >= 6)
                {
                    TimeSpan t = new TimeSpan(GlobalFunctions.intTryParse(split[1].Substring(0, 2)),
                        GlobalFunctions.intTryParse(split[1].Substring(2, 2)), GlobalFunctions.intTryParse(split[1].Substring(4, 2)));
                    DateTime nowutc = DateTime.UtcNow;
                    nowutc = nowutc.Add(-nowutc.TimeOfDay);
                    _timeOfFix = nowutc.Add(t);

                }

                _position = new Coordinate(GlobalFunctions.GPSToDecimalDegrees(split[4], split[5]),
                                           GlobalFunctions.GPSToDecimalDegrees(split[2], split[3]));
                if (split[6] == "1")
                    _fixQuality = FixQualityEnum.GPS;
                else if (split[6] == "2")
                    _fixQuality = FixQualityEnum.DGPS;
                else
                    _fixQuality = FixQualityEnum.Invalid;
                _noOfSats = Convert.ToByte(split[7]);
                GlobalFunctions.dblTryParse(split[8], out _dilution);
                GlobalFunctions.dblTryParse(split[9], out _altitude);
                _altitudeUnits = split[10][0];
                GlobalFunctions.dblTryParse(split[11], out _heightOfGeoid);
                GlobalFunctions.intTryParse(split[13], out _dGPSUpdate);
                _dGPSStationID = split[14];
            }
            catch { }
        }

        public DateTime TimeOfFix
        {
            get { return _timeOfFix; }
            //set { _timeOfFix = value; }
        }

        /// <summary>
        /// Coordinate of recieved position
        /// </summary>
        public Coordinate Position
        {
            get { return _position; }
            //set { _position = value; }
        }

        /// <summary>
        /// Fix quality (0=invalid, 1=GPS fix, 2=DGPS fix)
        /// </summary>
        public FixQualityEnum FixQuality
        {
            get { return _fixQuality; }
            internal set { _fixQuality = value; }
        }

        /// <summary>
        /// number of satellites being tracked.
        /// </summary>
        public byte NoOfSats
        {
            get { return _noOfSats; }
            //set { _noOfSats = value; }
        }

        /// <summary>
        /// Altitude above sea level.
        /// </summary>
        public double Altitude
        {
            get { return _altitude; }
            //set { _altitude = value; }
        }

        /// <summary>
        /// Altitude Units - M (meters).
        /// </summary>
        public char AltitudeUnits
        {
            get { return _altitudeUnits; }
            //set { _altitudeUnits = value; }
        }

        /// <summary>
        /// Horizontal dilution of position (HDOP).
        /// </summary>
        public double Dilution
        {
            get { return _dilution; }
            //set { _dilution = value; }
        }

        /// <summary>
        /// Height of geoid (mean sea level) above WGS84 ellipsoid.
        /// </summary>
        public double HeightOfGeoid
        {
            get { return _heightOfGeoid; }
            //set { _heightOfGeoid = value; }
        }

        /// <summary>
        /// Time in seconds since last DGPS update.
        /// </summary>
        public int DGPSUpdate
        {
            get { return _dGPSUpdate; }
            //set { _dGPSUpdate = value; }
        }

        /// <summary>
        /// DGPS station ID number.
        /// </summary>
        public string DGPSStationID
        {
            get { return _dGPSStationID; }
            //set { _dGPSStationID = value; }
        }

    }
}
